package cn.minhx.domain.strategy.service.rule.filter.factoty;

import cn.minhx.domain.strategy.model.entity.RuleActionEntity;
import cn.minhx.domain.strategy.service.annotation.LogicStrategy;
import cn.minhx.domain.strategy.service.rule.filter.ILogicFilter;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 规则工厂
 *
 * @author min
 */
@Service
public class DefaultLogicFactory {

    private final Map<String, ILogicFilter<?>> logicFilterMap = new ConcurrentHashMap<>();

    /**
     * 构造函数注入
     * 从Spring 4.3开始，如果类只有一个构造函数，那么无需显式标注 @Autowired
     */
    public DefaultLogicFactory(List<ILogicFilter<?>> logicFilters) {
        for (ILogicFilter<?> logicFilter : logicFilters) {
            LogicStrategy logicStrategy = AnnotationUtils.findAnnotation(logicFilter.getClass(), LogicStrategy.class);
            if (logicStrategy != null) {
                this.logicFilterMap.put(logicStrategy.logicModel().getCode(), logicFilter);
            }
        }
    }

    @SuppressWarnings("unchecked")
    public <T extends RuleActionEntity.RaffleEntity> Map<String, ILogicFilter<T>> openLogicFilter() {
        return (Map<String, ILogicFilter<T>>) (Map<?, ?>) logicFilterMap;
    }


    @Getter
    @AllArgsConstructor
    public enum LogicModel {

        /**
         * 【抽奖前规则】权重规则
         */
        RULE_WIGHT("rule_weight", "【抽奖前规则】根据抽奖权重返回可抽奖范围KEY", "before"),
        /**
         * 【抽奖前规则】黑名单规则
         */
        RULE_BLACKLIST("rule_blacklist", "【抽奖前规则】黑名单规则过滤，命中黑名单则直接返回", "before"),
        /**
         * 【抽奖中规则】次数锁
         */
        RULE_LOCK("rule_lock", "【抽奖中规则】次数锁", "center"),
        /**
         * 【抽奖后规则】
         */
        RULE_LUCK_AWARD("rule_luck_award", "【抽奖后规则】抽奖n次后，对应奖品可解锁抽奖", "after"),
        ;

        private final String code;
        private final String info;
        private final String type;

        public static boolean isCenter(String code) {
            return "center".equals(LogicModel.valueOf(code.toUpperCase()).type);
        }

        public static boolean isAfter(String code) {
            return "after".equals(LogicModel.valueOf(code.toUpperCase()).type);
        }

    }

}